import fs from 'fs';
import etag from 'etag';
import zlib from 'zlib';
import http from 'http';

import setHeader from '../header';
import { getSuffix } from '../common/util';
import { IServer } from '../../common/serve';

function end (request: http.IncomingMessage, response: http.ServerResponse, assetPath: string, assetZipPath: string): void {
    const { headers } = request;

    const ifNoneMatch = headers['if-none-match'];
    const isCache = ifNoneMatch && ifNoneMatch === etag(fs.statSync(assetZipPath));

    if (isCache) {
        response.statusCode = 304;
        response.end();
    } else {
        setHeader(request, response, assetZipPath, getSuffix(assetPath), true);

        const readStream = fs.createReadStream(assetZipPath);

        readStream.on('data', chunks => {
            response.write(chunks);
        });

        readStream.on('end', () => {
            response.statusCode = 200;
            response.end();
        });
    }
}

function gzipMod (request: http.IncomingMessage, response: http.ServerResponse, serverConfig: IServer, assetPath: string): void {
    const assetZipPath = assetPath + '.gz';

    if (fs.existsSync(assetZipPath)) {
        end(request, response, assetPath, assetZipPath);
        return;
    }

    const gzip = zlib.createGzip();
    const readStream = fs.createReadStream(assetPath);
    const writeStream = fs.createWriteStream(assetZipPath);

    readStream.pipe(gzip).pipe(writeStream);

    writeStream.on('close', () => {
        end(request, response, assetPath, assetZipPath);
    });
}

export default gzipMod;
